﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UnityMultiPlayerGameServer.Manager;
using GameProtocol;
using UnityMultiPlayerGameServer.Clients;
using UnityMultiPlayerGameServer.Data;

namespace UnityMultiPlayerGameServer
{
    internal class Server_UDP
    {
        Socket udpSocket;
        IPEndPoint ipPoint;
        //远程IP
        EndPoint remoteIP;

        byte[] buffer = new byte[1024 * 10240];

        Thread udpThread;

        public void Start(int port)
        {
            try
            {
                udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                ipPoint = new IPEndPoint(IPAddress.Any, port);
                remoteIP = new IPEndPoint(IPAddress.Any, port) as EndPoint;
                udpSocket.Bind(ipPoint);

                //SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                //args.SetBuffer(buffer, 0, buffer.Length);
                //args.RemoteEndPoint = remoteIP;
                //udpSocket.ReceiveFromAsync(args);

                udpThread = new Thread(ReceivePack);
                udpThread.Start();
                Console.WriteLine("UDP started");
            }
            catch (Exception e)
            {
                Console.WriteLine("初始化UDP时失败: " + e.Message);
                throw;
            }
        }

        public void ReceivePack()
        {
            while (true)
            {
                try
                {
                    int length = udpSocket.ReceiveFrom(buffer, ref remoteIP);
                    GamePack pack = (GamePack)GamePack.Descriptor.Parser.ParseFrom(buffer, 0, length);

                    //Console.WriteLine(pack.TestString);
                    Handlerequest(pack, remoteIP);
                }
                catch (Exception e)
                {
                    Console.WriteLine("接收UDP包时出错: " + e.Message);
                    continue;
                }               
            }        
        }

        public void Handlerequest(GamePack pack, EndPoint EndPoint)
        {
            if (pack == null || pack.UserInfo == null) return;
            Client client = ClientManager.Instance.FindClientByAccountID(pack.UserInfo.AccountID);
            //if (EndPoint == null) Console.WriteLine("edn null");
            //Console.WriteLine(remoteIP.ToString());
            if (client != null && client.RemoteIP == null)
            {
                client.RemoteIP = EndPoint;
            }
            ControllerManager.Instance.PackHandel_UDP(pack, client);
        }



        //public void ReceivePack()
        //{
        //    using (Socket sock = new Socket(SocketType.Dgram, ProtocolType.Udp))
        //    {
        //        byte[] buf = new byte[1];
        //        EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
        //        sock.Bind(ep);

        //        SocketAsyncEventArgs args = new SocketAsyncEventArgs();
        //        args.SetBuffer(buf, 0, buf.Length);
        //        args.RemoteEndPoint = ep;

        //        Assert.Throws<PlatformNotSupportedException>(() => sock.ReceiveFromAsync(args));
        //    }
        //}


        public void SendTo(GamePack pack, EndPoint point)
        {
            try
            {
                byte[] bytes = Message.PackData_UDP(pack);
                SocketAsyncEventArgs args = new SocketAsyncEventArgs();
                args.SetBuffer(bytes, 0, bytes.Length);
                args.RemoteEndPoint = point;
                udpSocket.SendToAsync(args);
            }
            catch (Exception e)
            {
                Console.WriteLine("UPD发送包时出错: " + e.Message);
                return;
            }
            
        }
    }
}
